home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Applications / QuArK / plugins / maptexpin.py < prev    next >
Text File  |  2004-01-05  |  10KB  |  330 lines

  1. ########################################################
  2. #
  3. #               Alternate Texture Position Plugin
  4. #
  5. #
  6. #                  by tiglari@hexenworld.met
  7. #     
  8. #
  9. #   You may freely distribute modified & extended versions of
  10. #   this plugin as long as you give due credit to tiglari &
  11. #   Armin Rigo. (It's free software, just like Quark itself.)
  12. #
  13. #   Please notify bugs & possible improvements to
  14. #   tiglari@hexenworld.net
  15. #  
  16. #
  17. ##########################################################
  18.  
  19. #$Header: /cvsroot/quark/runtime/plugins/maptexpin.py,v 1.3 2001/06/17 21:10:56 tiglari Exp $
  20.  
  21.  
  22. Info = {
  23.    "plug-in":       "Texture Pinning Plugin",
  24.    "desc":          "Texture positioning by `pinning'",
  25.    "date":          "Nov 18, 2000",
  26.    "author":        "tiglari",
  27.    "author e-mail": "tiglari@hexenworld.net",
  28.    "quark":         "Version 6.x" }
  29.  
  30. import quarkx
  31. import quarkpy.dlgclasses
  32. import tagging
  33. from quarkpy.maputils import *
  34.  
  35. #
  36. #  - These utilities should go to qutils or some such place,
  37. #    when this is prepared for stable release
  38. #
  39.  
  40. #
  41. # A utility for accessing attributes of objects
  42. #  (class instances) that might not be defined
  43. #
  44. def getAttr(object, attr, default=None):
  45.     if hasattr(object, attr):
  46.         return getattr(object,attr)
  47.     else:
  48.         return default
  49. #
  50. # ditto for deleting attributes
  51. #
  52. def delAttr(object, attr):
  53.     if hasattr(object, attr):
  54.          delattr(object, attr)
  55.  
  56. def appendToAttr(object, attr, thing):
  57.     if hasattr(object, attr):
  58.         getattr(object,attr).append(thing)
  59.     else:
  60.         setattr(object,attr,[thing])
  61.  
  62. def removeFromAttr(object, attr, thing):
  63.     getattr(object,attr).remove(thing)
  64.     if getattr(object,attr)==[]:
  65.         delattr(object,attr)
  66.  
  67.  
  68.  
  69.     
  70. #
  71. # Pinning dialog
  72. #
  73. #  ppdb's (quarkpy.dlgclasses) are set up like ordinary ones
  74. #   except for an additional initialization parameter 'label'
  75. #   that is used as a key for storing size/position info.
  76. #
  77. class VtxPinDlg(quarkpy.dlgclasses.placepersistent_dialogbox):
  78.     #
  79.     # dialog layout
  80.     #
  81.  
  82.     endcolor = AQUA
  83.     size = (140,140)
  84.     dfsep = 0.30
  85.  
  86.     dlgdef = """
  87.     {
  88.         Style = "9"
  89.         Caption = "Vertex Pinning"
  90.         
  91.         st:= { Txt = "st" Typ = "EF02"
  92.                Hint = "Tex coordinates for this vertex, W, H." }
  93.         
  94.         pin:= { Txt = "pin:" Typ = "ER"
  95.                    Hint = "# vertex being pinned (read-only)" }
  96.  
  97.         sep: = { Typ="S" Txt=""}
  98.  
  99.         exit:py = {Txt="" }
  100.         cancel:py = {Txt="" }
  101.     }"""
  102.  
  103.     def __init__(self,form,editor,label,msg,pos,face,facepins, repin):
  104.        self.editor = editor
  105.        self.src = quarkx.newobj(":")
  106.        texp = face.threepoints(2)
  107.  
  108.        self.src["pin"] = msg
  109.        
  110.        self.oldtex=texCoords(pos, texp, 128)
  111.        self.src["st"] = self.oldtex
  112.        self.facepins = facepins
  113.        self.pos = pos
  114.        self.face = face
  115.        self.repin = repin
  116.  
  117.        quarkpy.dlgclasses.placepersistent_dialogbox.__init__(self, form, self.src, label,
  118.           cancel = quarkpy.qtoolbar.button(
  119.             self.cancel,
  120.             "Cancel dialog",
  121.             ico_editor, 0,
  122.             "Cancel"),
  123.           exit = quarkpy.qtoolbar.button(
  124.             self.exit,
  125.             "Exit & apply changes",
  126.             ico_editor, 2,
  127.             "Exit & Apply")
  128.         )
  129.  
  130.     def exit(self, dlg):
  131.         quarkx.globalaccept()
  132.         st = self.src["st"]
  133.         st = st[0]/128, st[1]/128
  134.         editor=self.editor
  135.         pos = self.pos
  136.         pinned = getAttr(editor,'pinned')
  137.         facepins = self.facepins
  138.         if pinned is None:
  139.              pinned = editor.pinned = [(pos, st)]
  140.         else:
  141.              if self.repin:  # repin kludge
  142.                  for pin in editor.pinned[:]: # don't remove from orig.
  143.                      if not pin[0]-pos:
  144.                          editor.pinned.remove(pin)
  145.                          # could stop, but why not clearemall out?
  146.              editor.pinned.append((pos,st))
  147.              facepins.append((pos,st))
  148.         numpins = len(facepins)
  149.         if numpins == 3:
  150.             face = self.face
  151.             texp = solveForThreepoints(facepins[0], facepins[1], facepins[2])
  152.             newface = face.copy()
  153.             newface.setthreepoints(texp, 2)
  154.             undo = quarkx.action()
  155.             undo.exchange(face, newface)
  156.             editor.ok(undo, "move texture")
  157.         editor.invalidateviews()
  158.         qmacro.dialogbox.close(self, dlg)
  159.  
  160.  
  161.     def cancel(self, dlg):
  162.           qmacro.dialogbox.close(self, dlg)
  163.  
  164.  
  165.     
  166. #
  167. # New menu for vertexes
  168. #
  169. def vertexmenu(self, editor, view, oldmenu=quarkpy.maphandles.VertexHandle.menu.im_func):
  170.  
  171.     #
  172.     # enable/disable info
  173.     #
  174.     pinned = getAttr(editor,'pinned')
  175.     face = editor.layout.explorer.uniquesel
  176.     if face is not None:
  177.         if face.type!=":f":
  178.             face = None
  179.     facepins = []
  180.     repin = 0
  181.     if face is not None and pinned is not None:
  182.         #
  183.         # The idea here is that we only pay attention to
  184.         # pins on the selected face; we can't set more
  185.         # than three per face, but we can reset existing
  186.         # ones.  Ugh messy.
  187.         #
  188.         def onface(pin, face=face, pos = self.pos):
  189.             for cycle in face.vertices:
  190.                 for vertex in cycle:
  191.                     if not (pin[0]-vertex):
  192.                         return 1
  193.             return 0
  194.         facepins = filter(onface, pinned)
  195.         #
  196.         # The treatment of `repinning' seems awkward; it's removed
  197.         #   from facepins, and replaced in editor.pinned if the
  198.         #   dialog is executed.  Is there a cleaner way to do this?
  199.         #
  200.         for pin in facepins[:]:  # don't remove from original for loop
  201.             if not pin[0]-self.pos:
  202.                 repin=1
  203.                 facepins.remove(pin)
  204.  
  205.     def pinClick(m, self=self, editor=editor, facepins=facepins, face=face,repin=repin):
  206.         if len(facepins)==0:
  207.             msg = "first"
  208.         elif len(facepins)==1:
  209.             msg = "second"
  210.         elif len(facepins)==2:
  211.             msg = "third"
  212.         else:
  213.             quarkx.msgbox('3 pins, clear some',MT_ERROR,MB_OK)
  214.             return
  215.  
  216.         VtxPinDlg(quarkx.clickform, editor, 'vtxpin', msg, self.pos, face, facepins, repin)
  217.  
  218.     def clearPinClick(m, pos=self.pos, editor=editor, facepins=facepins):
  219.         for pin in facepins[:]:
  220.             if not (pos-pin[0]):
  221.                facepins.remove(pin)
  222.         for pin in editor.pinned[:]:
  223.             if not pos-pin[0]:
  224.                 editor.pinned.remove(pin)
  225.           
  226.         editor.invalidateviews()
  227.                 
  228.     def clearAllClick(m, editor=editor):
  229.         delattr(editor,'pinned')
  230.         editor.invalidateviews()
  231.     
  232.     if face is not None:
  233.         stString = " (%.1f, %.1f)"%texCoords(self.pos, face.threepoints(2), 128) 
  234.     else:
  235.         stString = ""
  236.     pinItem = qmenu.item('&Pin Vertex '+stString,pinClick,"|`pin' the texture on the face at the vertex. A face must be selected.\n\nAfter three pins have been set, the texture is repositioned so that the texture coordinates for the pinned points are as specified.")
  237.     stItem = qmenu.item(stString, None,"No action")
  238.     clearPin = qmenu.item('Clear Pin', clearPinClick)
  239.     clearPins = qmenu.item('Clear All Pins', clearAllClick)
  240.     
  241.     clearPin.state= qmenu.disabled
  242.     if pinned is None:
  243.         clearPins.state = qmenu.disabled
  244.     if (face is None) or (face.type != ':f'):
  245.         pinItem.state = qmenu.disabled
  246.         pinItem.hint = "|"+pinItem.hint + "\n\nThis menu item is disabled because it requires a face be selected"
  247.     if repin:
  248.         pinItem.text = 'Re&pin Vertex'
  249.         clearPin.state = qmenu.normal
  250.         
  251.     #
  252.     #  Promote/Demote of submenu seems like a good idea to
  253.     #   apply to other submenus.
  254.     #
  255.     promote = quarkx.setupsubset(SS_MAP, "Options")["Pinners"]
  256.  
  257.     def promoteClick(m):
  258.         quarkx.setupsubset(SS_MAP, "Options")["Pinners"]="1"
  259.          
  260.     def demoteClick(m):
  261.         quarkx.setupsubset(SS_MAP, "Options")["Pinners"]="0"
  262.  
  263.     if promote=="1":
  264.         promoteItem = qmenu.item('Demote Pinning',demoteClick, "|Pinning menu items get demoted to submenu")
  265.     else:
  266.         promoteItem = qmenu.item('Promote Pinning',promoteClick, "|Pinning menu items get promoted onto main vertex menu")
  267.  
  268.     pinList = [pinItem, clearPin, clearPins, promoteItem]
  269.     
  270.     if promote=="1":
  271.         pinners = pinList
  272.     else:
  273.         pinners = [qmenu.popup('Texture Pinning', pinList)]
  274.  
  275.  
  276.     return  pinners+oldmenu(self,editor,view)
  277.     
  278. quarkpy.maphandles.VertexHandle.menu = vertexmenu
  279.  
  280.  
  281. #
  282. # Now for drawing little boxes around pinned vertices
  283. #
  284. from tagging import drawredface # misnamed, oh well
  285.  
  286. def pinfinishdrawing(editor, view, oldmore=quarkpy.qbaseeditor.BaseEditor.finishdrawing):
  287.       cv = view.canvas()
  288.       try:
  289.          pins = editor.pinned
  290.       except (AttributeError):
  291.          pass
  292.       else:
  293.          cv.pencolor = MapColor("Duplicator")
  294.          for pin in pins:
  295.              p1 = view.proj(pin[0])
  296.              tagging.drawsquare(cv,p1,8)
  297.       try:
  298.          moving = editor.movingvertex
  299.          p1 = view.proj(moving)
  300.       except (AttributeError):
  301.          pass
  302.       else:
  303.          if view.info["type"] == "3D":
  304.               scalefactor = 50
  305.          else:
  306.              scalefactor = 30
  307.          scale = view.scale(moving)
  308.          for (color, axis) in (MapColor("Tag"), (1,0,0)), (MapColor("Bezier"), (0,1,0)),(MapColor("Duplicator"), (0,0,1)):
  309.              cv.pencolor = color
  310.              p0 = view.proj(moving)
  311.              p1 = view.proj(moving+(scalefactor/scale)*quarkx.vect(axis))
  312.              cv.line(p0, p1)
  313.                  
  314. #         else:
  315. #             cv.pencolor = MapColor("Bezier")
  316. #             tagging.drawsquare(cv,p1,8)
  317.               
  318.  
  319.       cv.pencolor=MapColor("Duplicator")
  320.       try:
  321.           for face in editor.frozenFaces:
  322.               drawredface(view,cv,face)
  323.       except (AttributeError):
  324.           pass
  325.       
  326.       oldmore(editor, view)
  327.  
  328. quarkpy.qbaseeditor.BaseEditor.finishdrawing = pinfinishdrawing
  329.  
  330. #$Log: #